package com.derbysoft.ota.application.translator.rs;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.CollectionUtils;

import com.derbysoft.modules.eip.translator.Translator;
import com.derbysoft.ota.application.translator.CodeTables;
import com.derbysoft.ota.application.util.POSTypes;
import com.derbysoft.ota.interfaces.protocol._2009a.HotelReservationType;
import com.derbysoft.ota.interfaces.protocol._2009a.ResGlobalInfoType;
import com.derbysoft.ota.interfaces.protocol._2009a.ResGuestsType;
import com.derbysoft.ota.interfaces.protocol._2009a.RoomStaysType;
import com.derbysoft.ota.interfaces.protocol._2009a.UniqueIDType;
import com.derbysoft.ota.interfaces.protocol._2009a.RoomStaysType.RoomStay;
import com.derbysoft.remote.dswitch.generic.dto.UniqueIDDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationRS;
import com.derbysoft.remote.dswitch.hotel.dto.ReservationRoomStayDTO;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.googlecode.functionalcollections.FunctionalIterables;

public class HotelReservationTypeRSTranslator
		implements
		Translator<Map.Entry<HotelReservationRS, HotelReservationType>, HotelReservationType> {

	private Translator<RoomStayRSSource, RoomStay> roomStayRSTranslator;
	private Translator<Entry<HotelReservationRS, ResGlobalInfoType>, ResGlobalInfoType> resGlobalInfoTranslator;
	
	@Inject
	public HotelReservationTypeRSTranslator(
		Translator<Entry<HotelReservationRS, ResGlobalInfoType>, ResGlobalInfoType> resGlobalInfoTranslator,
		Translator<RoomStayRSSource, RoomStay> roomStayRSTranslator) {
		
		this.resGlobalInfoTranslator = resGlobalInfoTranslator;
		this.roomStayRSTranslator = roomStayRSTranslator;
	}

	@Override
	public HotelReservationType translate(Entry<HotelReservationRS, HotelReservationType> source) {
		HotelReservationRS switchRS = source.getKey();
		HotelReservationType otaRQ = source.getValue();
		HotelReservationType dest = new HotelReservationType();
		dest.setPOS(POSTypes.of(switchRS.getOriginalBuyer().getId()));
		dest.getUniqueID().add(providerId(switchRS.getOriginalProvider()));
		dest.setResGuests((ResGuestsType) otaRQ.getResGuests());
		dest.setRoomStays(roomStays(otaRQ, switchRS));
		dest.setResGlobalInfo(resGlobalInfo(switchRS, otaRQ));
		return dest;
	}

	private ResGlobalInfoType resGlobalInfo(HotelReservationRS switchRS, HotelReservationType otaRQ) {
		return resGlobalInfoTranslator.translate(Maps.immutableEntry(switchRS, otaRQ.getResGlobalInfo()));
	}

	private RoomStaysType roomStays(final HotelReservationType otaRQ, HotelReservationRS switchRS) {
		final HotelReservationDTO hotelReservation = switchRS.getHotelReservation();
        List<ReservationRoomStayDTO> switchRoomStays = hotelReservation.getRoomStays();
        if (CollectionUtils.isEmpty(switchRoomStays)) {
            return null;
        }
        RoomStaysType roomStaysType = new RoomStaysType();
        roomStaysType.getRoomStay().addAll(
			FunctionalIterables.make(switchRoomStays).map(
				new Function<ReservationRoomStayDTO, RoomStay>() {
					public RoomStay apply(ReservationRoomStayDTO from) {
						return roomStayRSTranslator.translate(
							new RoomStayRSSource(otaRQ, hotelReservation.getHotelRef(), from)
						);
					}
				}
			).toCollection()
		);
		
		return roomStaysType;
	}

	private UniqueIDType providerId(UniqueIDDTO switchProvider) {
		UniqueIDType otaProvider = new UniqueIDType();
		otaProvider.setID(switchProvider.getId());
		otaProvider.setType(CodeTables.UIT_HOTEL);
		return otaProvider;
	}

}
